package com.house365.core.task;

import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.os.AsyncTask;
import android.widget.ListView;

import com.house365.core.R;
import com.house365.core.adapter.BaseListAdapter;
import com.house365.core.application.BaseApplication;
import com.house365.core.bean.common.CommonTaskInfo;
import com.house365.core.constant.CorePreferences;
import com.house365.core.http.exception.HtppApiException;
import com.house365.core.http.exception.HttpParseException;
import com.house365.core.http.exception.NetworkUnavailableException;
import com.house365.core.util.ActivityUtil;
import com.house365.core.util.RefreshInfo;
import com.house365.core.util.TimeUtil;
import com.house365.core.util.ViewUtil;
import com.house365.core.view.ListFooterView;
import com.house365.core.view.LoadingDialog;
import com.house365.core.view.pulltorefresh.PullToRefreshListView;

public abstract class BaseListAsyncTask<T> extends
		AsyncTask<Object, Object, Object> {
	protected BaseApplication mApplication;
	protected LoadingDialog loadingDialog;
	protected Context context;
	protected int loadingresid;

	protected RefreshInfo listRefresh;
	private ListFooterView footerView;
	private BaseListAdapter adapter;
	private ListView listView;
	private PullToRefreshListView pullListView;

	public BaseListAsyncTask(Context context, int loadingResId,
			PullToRefreshListView listView, RefreshInfo listRefresh,
			BaseListAdapter adapter) {
		this.context = context;
		this.loadingresid = loadingResId;
		this.pullListView = listView;
		this.listRefresh = listRefresh;
		this.adapter = adapter;
		mApplication = (BaseApplication) ((Activity) context).getApplication();
	}

	public BaseListAsyncTask(Context context, PullToRefreshListView listView,
			RefreshInfo listRefresh, BaseListAdapter adapter) {
		super();
		this.context = context;
		this.listRefresh = listRefresh;
		this.adapter = adapter;
		this.pullListView = listView;
		mApplication = (BaseApplication) ((Activity) context).getApplication();
	}

	public BaseListAsyncTask(Context context, ListView listView,
			ListFooterView footerView, RefreshInfo listRefresh,
			BaseListAdapter adapter) {
		super();
		this.context = context;
		this.listRefresh = listRefresh;
		this.footerView = footerView;
		this.adapter = adapter;
		this.listView = listView;
		mApplication = (BaseApplication) ((Activity) context).getApplication();
	}

	public BaseListAsyncTask(Context context) {
		super();
		this.context = context;
		this.mApplication = (BaseApplication) ((Activity) context)
				.getApplication();
	}

	public LoadingDialog getLoadingDialog() {
		if (loadingDialog == null) {
			loadingDialog = new LoadingDialog(this.context, R.style.dialog,
					loadingresid);
			loadingDialog.setCancelable(true);

		}
		return loadingDialog;
	}

	protected void onPreExecute() {
		if (loadingresid > 0) {
			getLoadingDialog().show();
		}
		if (listRefresh != null) {
			if (pullListView != null) {
				ViewUtil.onPreLoadingListData(listRefresh, pullListView,
						adapter);
			} else {
				ViewUtil.onPreLoadingListData(listRefresh, listView, footerView);
			}
		}
	}

	@Override
	protected CommonTaskInfo<List<T>> doInBackground(Object... params) {
		CommonTaskInfo<List<T>> commonTaskInfo = new CommonTaskInfo<List<T>>();
		commonTaskInfo.setResult(CommonTaskInfo.SUCCESS);
		List<T> v = null;
		boolean catchE = false;
		try {
			v = onDoInBackgroup();
		} catch (NetworkUnavailableException e) {
			CorePreferences.ERROR(e);
			catchE = true;
			commonTaskInfo.setResult(CommonTaskInfo.NETWORK_UNAVAILABLE);
		} catch (HtppApiException e) {
			CorePreferences.ERROR(e);
			catchE = true;
			commonTaskInfo.setResult(CommonTaskInfo.HTTP_REQUEST_ERROR);
		} catch (HttpParseException e) {
			CorePreferences.ERROR(e);
			catchE = true;
			commonTaskInfo.setResult(CommonTaskInfo.PARSE_ERROR);
		}
		
		pageDecrement(catchE);
		commonTaskInfo.setData(v);
		return commonTaskInfo;
	}
	
	private void pageDecrement(boolean catchE) {
		if(catchE){
			if (!listRefresh.refresh) {
				listRefresh.page--;
			}
		}
	}

	@Override
	protected void onPostExecute(Object result) {
		if (loadingresid > 0) {
			getLoadingDialog().dismiss();
		}
		if (context instanceof Activity && ((Activity) context).isFinishing()) {
			return;
		}
		CommonTaskInfo<List<T>> commonTaskInfo = (CommonTaskInfo<List<T>>) result;
		if (commonTaskInfo.getResult() == CommonTaskInfo.NETWORK_UNAVAILABLE) {
			if (listRefresh.refresh) {
				//通知头部刷新成功
				pullListView.onRefreshComplete(TimeUtil.toDateAndTime(System.currentTimeMillis()/1000));
			}else{
				//通知底部加载成功
				pullListView.onRefreshComplete();
			}
			onNetworkUnavailable();
			return;
		}
		if (commonTaskInfo.getResult() == CommonTaskInfo.HTTP_REQUEST_ERROR) {
			if (listRefresh.refresh) {
				//通知头部刷新成功
				pullListView.onRefreshComplete(TimeUtil.toDateAndTime(System.currentTimeMillis()/1000));
			}else{
				//通知底部加载成功
				pullListView.onRefreshComplete();
			}
			onHttpRequestError();
			return;
		}
		if (commonTaskInfo.getResult() == CommonTaskInfo.PARSE_ERROR) {
			if (listRefresh.refresh) {
				//通知头部刷新成功
				pullListView.onRefreshComplete(TimeUtil.toDateAndTime(System.currentTimeMillis()/1000));
			}else{
				//通知底部加载成功
				pullListView.onRefreshComplete();
			}
			onParseError();
			return;
		}
		List v = commonTaskInfo.getData();
		if (listRefresh != null) {
			if (pullListView != null) {
				ViewUtil.onListDataComplete(context, v, listRefresh, adapter,
						pullListView);
			} else {
				ViewUtil.onListDataComplete(context, v, listRefresh, adapter,
						listView, footerView);
			}

			if (listRefresh.isRefresh()) {
				onAfterRefresh(v);
			}

		}
	}

	public PullToRefreshListView getPullListView() {
    return pullListView;
  }
	
	protected void onAfterRefresh(List<T> v) {
	}

	public abstract List<T> onDoInBackgroup()
			throws NetworkUnavailableException, HtppApiException,
			HttpParseException;

	/**
	 * 当用户取消加载框的时候调用，前提打开加载框
	 */
	protected void onDialogCancel() {

	}

	/**
	 * 当网络不可用时候调用
	 */
	protected void onNetworkUnavailable() {
		ActivityUtil.showToast(context, R.string.text_network_unavailable);
	}

	/**
	 * 当http请求发生错误时调用，包括接口错误，请求超时
	 */
	protected void onHttpRequestError() {
		ActivityUtil.showToast(context, R.string.text_http_request_error);
	}

	/**
	 * 当数据解析异常时调用
	 */
	protected void onParseError() {
		ActivityUtil.showToast(context, R.string.text_http_parse_error);
	}
}
